package com.wt.demo.threadtest.concurrentsearch;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description
 * @author: wangtao
 * @date:13:42 2018/6/11
 * @email:tao8.wang@changhong.com
 */
public class ConcurrentSearch {

    static int[] arr = new int[1000];
    static ExecutorService exec = Executors.newCachedThreadPool();
    static final int THREAD_NUM = 4;
    static AtomicInteger result = new AtomicInteger(-1);

    public static int search(int searchValue, int pos, int end, String name) {
        for (int i = pos; i < end; i++) {
            System.out.println(name + " is searching value arr[" + i + "]");
            if (result.get() > 0) {
                return result.get();
            }
            if (arr[i] == searchValue) {
                if (result.compareAndSet(-1, i)) {
                    return result.get();
                }
            }
        }
        return -1;
    }

    public static class SearchTask implements Callable<Integer> {

        private int searchValue;
        private int pos;
        private int end;
        private String name;

        public SearchTask(int searchValue, int pos, int end, String name) {
            this.searchValue = searchValue;
            this.pos = pos;
            this.end = end;
            this.name = name;
        }

        @Override
        public Integer call() throws Exception{
            int re = search(searchValue, pos, end, name);
            return re;
        }
    }

    public static int pSearch(int searchValue) throws InterruptedException {
        int subArraySize = arr.length / THREAD_NUM + 1;
        List<Future<Integer>> re = new ArrayList<>();
        for (int i = 0; i < arr.length; i += subArraySize) {
            int end = i + subArraySize;
            end = end > arr.length ? arr.length : end;
            re.add(exec.submit(new SearchTask(searchValue, i, end, "thread " + i / subArraySize)));
        }
        for (Future<Integer> f : re) {
            try {
                if (f.get() > 0) return f.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("reSize:" + re.size());
        return -1;
    }

    public static void main(String[] args) throws InterruptedException {
        arr[600] = 199;
        int i = pSearch(199);
        System.out.println("arg[" + i + "]" + "=199");
    }

}
